package com.xxg.renrenlogin.service.common;

import com.auth0.jwt.exceptions.JWTCreationException;
import com.auth0.jwt.exceptions.JWTVerificationException;
import com.auth0.jwt.interfaces.DecodedJWT;
import com.xxg.renrenlogin.cache.RrenrenShopUserCache;
import com.xxg.renrenlogin.domain.result.BaseResult;
import com.xxg.renrenlogin.domain.result.LoginReturnCodeEnum;
import com.xxg.renrenlogin.domain.result.TokenResult;
import com.xxg.renrenlogin.exception.ErrorMessage;
import com.xxg.renrenlogin.exception.RenrenLoginException;
import com.xxg.renrenlogin.util.DateTimeUtil;
import com.xxg.renrenlogin.util.JwtUtils;
import com.xxg.renrenlogin.util.RSAUtil;
import lombok.AllArgsConstructor;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

/**
 * 令牌公共类
 *
 * @author xxg
 * @date 2020/9/28
 */
@Component
@AllArgsConstructor
public class TokenCommon {
    private static final Logger logger = LoggerFactory.getLogger(TokenCommon.class);
    private final RrenrenShopUserCache accountInfoCache;

    /**
     * 生成新的token令牌
     *
     * @param account  加密的信息
     * @param userType 用户身份类型
     * @param userId   用户ID
     * @param shopId   店铺ID，-1表示没有店铺
     * @return 新的token
     */
    public BaseResult createNewToken(String account, String userType, String userId, String shopId) {
        String timestamp = DateTimeUtil.getTimestampString();
        // 更新token的时间戳信息
        accountInfoCache.updateTokenAt(account, timestamp);
        // 生成新的token
        String loginToken;
        try {
            loginToken = JwtUtils.createJwtToken(account, timestamp, userId, shopId, JwtUtils.SECRET);
        } catch (JWTCreationException e) {
            logger.error(ErrorMessage.CREATE_TOKEN_ERROR, e);
            return new BaseResult(LoginReturnCodeEnum.FAILURE, ErrorMessage.CREATE_TOKEN_ERROR, null);
        }
        TokenResult tokenInfo;
        tokenInfo = new TokenResult(loginToken, userType);
        return new BaseResult(LoginReturnCodeEnum.SUCCESS, "", tokenInfo);
    }

    /**
     * 加密账号
     *
     * @param account 账号
     * @return 加密账号
     * @throws RenrenLoginException 异常信息
     */
    private String encryptAccount(String account) throws RenrenLoginException {
        String accountCrypto;
        try {
            accountCrypto = RSAUtil.encrypt(account, RSAUtil.PUB_KEY);
        } catch (Exception e) {
            logger.error(ErrorMessage.ENCRYPT_ACCOUNT_ERROR, e);
            throw new RenrenLoginException(ErrorMessage.ENCRYPT_ACCOUNT_ERROR);
        }
        return accountCrypto;
    }

    /**
     * 从令牌中获取userId
     *
     * @param token 令牌
     * @return userId
     * @throws RenrenLoginException 异常信息
     */
    public String getUserId(String token) throws RenrenLoginException {
        // token验证
        DecodedJWT decodedToken;
        try {
            decodedToken = JwtUtils.verifyJwtToken(token, JwtUtils.SECRET);
        } catch (JWTVerificationException e) {
            logger.error(ErrorMessage.VERIFY_TOKEN_ERROR, e);
            throw new RenrenLoginException(ErrorMessage.VERIFY_TOKEN_ERROR);
        }
        return decodedToken.getIssuer();
    }
}
